<template>
  <div v-loading="isRequesting">
    <div class="g-oneline-space-between">
      <!--显示模式-->
      <el-radio-group v-model="showMode" size="small">
        <el-radio-button label="menuId">{{ $t('MenuManager.route') }}</el-radio-button>
        <el-radio-button label="menuNameZhCn">{{ $t('MenuManager.menuNameZhCn') }}</el-radio-button>
        <el-radio-button label="menuNameZhTw">{{ $t('MenuManager.menuNameZhTw') }}</el-radio-button>
        <el-radio-button label="menuNameEn">{{ $t('MenuManager.menuNameEn') }}</el-radio-button>
      </el-radio-group>
      <!--保存按钮-->
      <el-button
        v-if="$hasPer('save')"
        icon="el-icon-tickets"
        size="small"
        type="primary"
        @click="save"
      >
        {{ $t('button.save') }}
      </el-button>
    </div>
    <div style="flex: 1;display: flex;align-items: flex-start;font-size: 14px;padding-right: 8px;">
      <div style="text-align: left;margin: 5px;padding: 5px;width: 50%;background: #f4f3ff">
        <div
          style="flex: 1;display: flex;align-items: center;justify-content: space-between;padding-left: 24px;padding-right: 24px"
        >
          <div>
            <el-button size="mini" type="text" @click="addBefore">
              {{ $t('MenuManager.addBefore') }}
            </el-button>
            <el-button size="mini" type="text" @click="addAfter">
              {{ $t('MenuManager.addAfter') }}
            </el-button>
            <el-button size="mini" type="text" @click="addChild">
              {{ $t('MenuManager.addChild') }}
            </el-button>
            <el-button size="mini" type="text" @click="deleteNode">
              {{ $t('MenuManager.deleteNode') }}
            </el-button>
          </div>
          <div>
            <el-button size="mini" type="text" @click="clearMenu">
              {{ $t('MenuManager.clearMenu') }}
            </el-button>
          </div>
        </div>
        <el-tree
          ref="menuManagerTree"
          :data="menuTree"
          default-expand-all
          :draggable="true"
          :highlight-current="true"
          node-key="menuId"
          :props="{ children: 'children' }"
          @node-click="clickNode"
        >
          <span
            slot-scope="{ node, data }"
            :data="node"
            style="flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;"
          >
            <span>{{ data[showMode] }}</span>
            <div>
              <span v-for="(item, index) in data.menuFuncList" :key="index">
                <el-tag
                  v-if="item.bindButton"
                  effect="dark"
                  size="mini"
                  style="margin-right: 3px"
                  type="success"
                >
                  {{ $store.getters['dict/dictValue'](item.bindButton) }}
                </el-tag>
              </span>
            </div>
          </span>
        </el-tree>
      </div>
      <div style="margin: 5px;width:50%;padding-top: 30px">
        <el-form
          :disabled="formData.unActive"
          label-width="120px"
          :model="formData"
          size="medium"
          style="text-align: left;"
        >
          <el-row>
            <el-col :span="22">
              <!--菜单编号 菜单完整路由地址-->
              <el-form-item :label="$t('MenuManager.route')">
                <el-input v-if="formData.isCatalog" v-model="formData.menuId" />
                <el-select
                  v-else
                  ref="select"
                  v-model="formData.menuId"
                  :placeholder="$t('select.placeholder')"
                  style="width: 100%"
                  @change="nodeChange"
                  @focus="nodeFocus"
                >
                  <el-option
                    v-for="item in routeList"
                    :key="item.menuId"
                    :disabled="isDisabledMenuId(item.menuId)"
                    :label="item.menuId"
                    :value="item.menuId"
                  />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="22">
              <!--菜单名称英文-->
              <el-form-item :label="$t('MenuManager.menuNameEn')">
                <el-input v-model="formData.menuNameEn" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="22">
              <!--菜单名称中文简体-->
              <el-form-item :label="$t('MenuManager.menuNameZhCn')">
                <el-input v-model="formData.menuNameZhCn" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="22">
              <!--菜单名称中文繁体-->
              <el-form-item :label="$t('MenuManager.menuNameZhTw')">
                <el-input v-model="formData.menuNameZhTw" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item :label="$t('MenuManager.isCatalog')">
                <el-switch v-model="formData.isCatalog" :disabled="isDisabledCatalog" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="$t('MenuManager.isOpen')">
                <el-switch v-model="formData.isOpen" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item :label="$t('MenuManager.isForbidden')">
                <el-switch v-model="formData.isForbidden" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="!formData.isCatalog">
            <el-col :span="22">
              <!--功能绑定-->
              <el-form-item :label="$t('MenuManager.funcBind')">
                <el-button round size="mini" type="primary" @click="addFunc">
                  {{ $t('MenuManager.addFunc') }}
                </el-button>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="!formData.isCatalog">
            <el-col :span="24">
              <!--菜单绑定的功能列表-->
              <el-table border :data="formData.menuFuncList" height="250px">
                <el-table-column align="center" :label="$t('table.NO')" width="50">
                  <template slot-scope="scope">
                    <span>{{ scope.$index + 1 }}</span>
                  </template>
                </el-table-column>
                <el-table-column align="center" :label="$t('MenuManager.bindFunc')">
                  <template slot-scope="scope">
                    <el-select
                      v-model="scope.row.funcId"
                      :placeholder="$t('select.placeholder')"
                      size="mini"
                    >
                      <el-option
                        v-for="item in funcList"
                        :key="item.funcId"
                        :label="item.funcName"
                        :value="item.funcId"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column align="center" :label="$t('MenuManager.bindButton')">
                  <template slot-scope="scope">
                    <el-select
                      v-model="scope.row.bindButton"
                      :placeholder="$t('select.placeholder')"
                      size="mini"
                    >
                      <el-option
                        v-for="item in $store.getters['dict/dictOptions']('BUTTON')"
                        :key="item.code"
                        :label="item.value"
                        :value="item.code"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <!--操作列-->
                <el-table-column align="center" :label="$t('table.operate')">
                  <template slot-scope="scope">
                    <!--删除按钮-->
                    <el-button size="mini" type="danger" @click="rowDelete(scope.$index)">
                      {{ $t('button.delete') }}
                    </el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-col>
          </el-row>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
import { menuSave } from '../../../api/sys/menu'
import { funcList } from '../../../api/sys/func'
import { ROOT_MENU_ID } from '../../../const/server-map'
import { privateRoutes } from '../../../router'
import { routesFormatToMenus } from '../../../store/modules/menu'

export default {
  name: 'MenuManager',
  props: {},
  data() {
    return {
      isRequesting: false,
      // 菜单树数据
      menuTree: [],
      // 显示模式 /路由/中文简体/中文繁体/英文
      showMode: 'menuNameZhCn',
      // menu表单内容,也是当前节点
      formData: {
        unActive: true
      },
      currentNode: {},
      newData: {
        menuId: 'new node',
        menuNameEn: 'new node',
        menuNameZhCn: 'new node',
        menuNameZhTw: 'new node',
        isCatalog: false,
        isOpen: false,
        isForbidden: false,
        menuFuncList: []
      },
      addFuncDialogVisible: false,
      funcList: [],
      routeList: [],
      // 菜单列表（已经选择的菜单列表）
      postMenuList: [],
      // 暂存的节点菜单
      preMenuId: ''
    }
  },
  computed: {
    // 判断当前菜单是否随意切换状态（目录《==》菜单）
    isDisabledCatalog() {
      if (this.formData.isCatalog) {
        return this.formData.children && this.formData.children.length > 0
      } else {
        return false
      }
    }
  },
  created() {
    this.postMenuList = this.$deepCopy(this.$store.getters['menu/getSessionPostMenuList'])
  },
  mounted() {
    this.pageInit()
  },
  methods: {
    // select focus
    nodeFocus() {
      this.preMenuId = this.formData.menuId
    },
    // select change
    nodeChange(menuId) {
      // 将新的menuId添加到postMenuList，
      this.postMenuList.push({
        menuId: menuId
      })
      // 强制失去焦点，让客户再次点击，刷新暂存的菜单preMenuId
      setTimeout(() => {
        this.$refs.select.blur()
      }, 50)
      // 将老的menuId从postMenuList中删除
      const index = this.postMenuList.findIndex(item => item.menuId === this.preMenuId)
      if (index < 0) return
      this.postMenuList.splice(index, 1)
    },
    pageInit() {
      this.menuTree = this.$deepCopy(this.$store.getters['menu/getSessionPostMenuTree'])
      this.initFuncListInfo()
    },
    /* 初始化功能列表*/
    async initFuncListInfo() {
      try {
        this.isRequesting = true
        const response = await funcList()
        this.funcList = response.data
        this.routeList = routesFormatToMenus(privateRoutes, '')
      } catch (error) {
        console.log(error)
      } finally {
        this.isRequesting = false
      }
    },
    addBefore() {
      if (Object.keys(this.currentNode).length === 0) return
      const newNode = JSON.parse(JSON.stringify(this.newData))
      this.$refs.menuManagerTree.insertBefore(newNode, this.currentNode)
      this.$refs.menuManagerTree.setCurrentNode(newNode)
      this.formData = newNode
    },
    addAfter() {
      if (Object.keys(this.currentNode).length === 0) return
      const newNode = JSON.parse(JSON.stringify(this.newData))
      this.$refs.menuManagerTree.insertAfter(newNode, this.currentNode)
      this.$refs.menuManagerTree.setCurrentNode(newNode)
      this.formData = newNode
    },
    addChild() {
      const newNode = JSON.parse(JSON.stringify(this.newData))
      if (this.menuTree.length === 0) {
        this.formData = newNode
        this.formData.isCatalog = true
        this.menuTree.push(this.formData)
      } else {
        if (Object.keys(this.currentNode).length === 0) return
        this.$refs.menuManagerTree.append(newNode, this.currentNode)
        this.$refs.menuManagerTree.setCurrentNode(newNode)
        this.formData = newNode
        this.formData.isCatalog = true
      }
    },
    deleteNode() {
      if (this.currentNode.key === '/MenuManager') {
        return this.$message({
          message: this.$t('MenuManager.deleteTip'),
          type: 'error',
          duration: 1500
        })
      }
      this.$refs.menuManagerTree.remove(this.currentNode)
      const index = this.postMenuList.findIndex(item => item.menuId === this.currentNode.key)
      if (index > -1) {
        this.postMenuList.splice(index, 1)
      }
      this.formData = { unActive: true }
    },
    // 清空tree
    clearMenu() {
      this.menuTree = []
      this.formData = {
        unActive: true
      }
      this.currentNode = {}
      this.postMenuList = []
    },
    // 点击tree
    clickNode(data, node) {
      this.formData = data
      this.currentNode = node
    },
    addFunc() {
      this.formData.menuFuncList.push({
        menuId: this.formData.menuId,
        order: this.formData.menuFuncList.length
      })
    },
    async save() {
      try {
        this.isRequesting = true
        const data = this.menuTreeToMenuList(this.menuTree)
        // 检查是否有菜单管理
        if (!this.checkMenu(data)) {
          return this.$message({
            message: this.$t('MenuManager.deleteTip'),
            type: 'error',
            duration: 1500
          })
        }
        let countOrder = 0
        for (const tempMenu of data) {
          tempMenu.order = countOrder
          countOrder = countOrder + 1
        }
        await menuSave(data, { msgSuccess: true, msgError: true })
        this.$store.dispatch('menu/initSessionPostMenuList')
      } catch (error) {
        console.log(error)
      } finally {
        this.isRequesting = false
      }
    },
    // 检测菜单是否存在/MenuManager
    checkMenu(menuList) {
      let isExist = false
      for (const item of menuList) {
        if (item.menuId === '/MenuManager') {
          isExist = true
          break
        }
      }
      return isExist
    },
    rowDelete(index) {
      this.formData.menuFuncList.splice(index, 1)
    },
    // 菜单树转菜单集合
    menuTreeToMenuList(menuTreeData, parentMenuId) {
      if (!parentMenuId) {
        parentMenuId = ROOT_MENU_ID
      }
      let retMenuList = []
      for (const tempMenu of menuTreeData) {
        const newMenu = {
          menuId: tempMenu.menuId,
          menuNameEn: tempMenu.menuNameEn,
          menuNameZhCn: tempMenu.menuNameZhCn,
          menuNameZhTw: tempMenu.menuNameZhTw,
          isCatalog: tempMenu.isCatalog,
          isForbidden: tempMenu.isForbidden,
          isOpen: tempMenu.isOpen,
          parentMenu: parentMenuId,
          menuFuncList: tempMenu.menuFuncList
        }
        retMenuList.push(newMenu)
        const childrenMenu = tempMenu.children
        if (childrenMenu && childrenMenu.length > 0) {
          retMenuList = retMenuList.concat(this.menuTreeToMenuList(childrenMenu, tempMenu.menuId))
        }
      }
      return retMenuList
    },
    // 判断当前下拉菜单路由菜单每行的状态是否为diabled
    isDisabledMenuId(key) {
      const res = this.postMenuList.find(item => {
        return item.menuId === key
      })
      return Boolean(res)
    }
  }
}
</script>

<style scoped></style>
